package com.ecric.sensor;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import java.util.Iterator;
import java.util.List;

public class GradienterActivity extends AppCompatActivity implements SensorEventListener{

    GradienterView show;
    //定义水平仪能处理的最大倾斜角，超过该角度，气泡将直接位于边界
    int MAX_ANGLE = 30;
    SensorManager sm;
    /**方向传感器*/
    private Sensor orientation;
    private List<Sensor> deviceSensors;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gradienter);
        show = (GradienterView) findViewById(R.id.show);
        sm = (SensorManager) getSystemService(SENSOR_SERVICE);
        //获取手机上支持的所有传感器
        deviceSensors = sm.getSensorList(Sensor.TYPE_ALL);
        if (!check(Sensor.TYPE_ORIENTATION)) {
            Toast.makeText(this, "当前设备不支持方向传感器", Toast.LENGTH_SHORT).show();
        }else {
            orientation = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        if (orientation != null){
            sm.registerListener(this,orientation,SensorManager.SENSOR_DELAY_FASTEST);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (orientation != null){
            sm.unregisterListener(this);
        }
    }


    @Override
    public void onSensorChanged(SensorEvent event) {
        float[] values = event.values;
        switch (event.sensor.getType()){
            case Sensor.TYPE_ORIENTATION:
                //获取与y轴的夹角
                float AngleY = values[1];
                //获取与z轴的夹角
                float Anglez = values[2];
                //气泡位于中间时(水平仪完全水平)， 气泡的位置x，y坐标
                int x = (show.back.getWidth() - show.bubble.getWidth()) / 2 ;
                int y = (show.back.getHeight() - show.bubble.getHeight()) / 2 ;
                //如果与Z轴的倾斜角还在最大角度之内
                if (Math.abs(Anglez) <= MAX_ANGLE){
                    //根据与Z轴的倾斜角度计算x坐标的变化值（倾斜角度越大，变化越大）
                    int deltaX = (int) ((show.back.getWidth() - show.bubble.getWidth()) / 2 * Anglez / MAX_ANGLE);
                    x += deltaX;
                }else if (Anglez > MAX_ANGLE){//如果与z轴的倾斜角已经大于MAX_ANGLE，气泡应到左边
                    x = 0;
                }else {//如果与Z轴的倾斜角已经小于负的MAX_ANGLE 气泡应到最右边
                    x = show.back.getWidth() - show.bubble.getWidth();
                }

                //如果与Y轴的倾斜角还在最大角度之内
                if (Math.abs(AngleY) <= MAX_ANGLE){
                    //根据与y轴的倾斜角度计算x坐标的变化值（倾斜角度越大，变化越大）
                    int deltaY = (int) ((show.back.getHeight() - show.bubble.getHeight()) / 2 * AngleY / MAX_ANGLE);
                    y += deltaY;
                }else if (AngleY > MAX_ANGLE){//如果与y轴的倾斜角已经大于MAX_ANGLE，气泡应到左边
                    y = show.back.getHeight() - show.bubble.getHeight();
                }else {//如果与y轴的倾斜角已经小于负的MAX_ANGLE 气泡应到最右边
                    y = 0;
                }

                if (isContain(x,y)){
                    show.bubbleX = x;
                    show.bubbleY = y;
                }
                show.postInvalidate();
                break;
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }




    /**
     * 检测设备是否支持某类型的传感器
     *
     * @param type 传感器的类型
     * @return true  当前设备支持该类型的传感器  否则不支持
     */
    private boolean check(int type) {
        Iterator<Sensor> iterator = deviceSensors.iterator();
        while (iterator.hasNext()) {
            Sensor sensor = iterator.next();
            if (sensor.getType() == type) {
                return true;
            }
        }
        return false;
    }


    /**
     * 计算x y点的坐标是否处于水平仪的仪表盘内
     */
    private boolean isContain(int x,int y){
        //计算气泡的愿新坐标x，y
        int bubbleCX = x + show.bubble.getWidth() / 2;
        int bubbleCY = y + show.bubble.getHeight() / 2;
        //计算水平仪仪表盘的圆心坐标x，y
        int backCX = show.back.getWidth() / 2;
        int backCY = show.back.getHeight() / 2;
        //计算气泡的圆心与水平仪仪表盘的圆心之间的距离
        double distance = Math.sqrt((bubbleCX - backCX) * (bubbleCX - backCX) + (bubbleCY - backCY) * (bubbleCY - backCY));
        //若两个圆心的距离小于它们的半径差，即可认为处于该点的气泡依然位于仪表盘内
        if (distance < (show.back.getWidth() - show.bubble.getWidth()) / 2){
            return true;
        }
        return false;
    }


}
